<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>math</title>
</head>
<body onload="main()">
    <canvas id="c" width="400" height="400"></canvas>
</body>

<script type="notjs" id="vs-src">
    attribute vec2 a_position;
    uniform mat4 u_projMatrix;
    void main(){
        gl_Position = u_projMatrix * vec4(a_position, 0.0, 1.0);
    }

</script>

<script type="notjs" id="fs-src">
    precision mediump float;
    void main(){
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
</script>

<script src="demo03/lib/webgl-utils.js"></script>
<script type="text/javascript">

    function cal() {
        var v1 = [1.0, 2.0];
        var v2 = [-6.0, 3.0];

        console.log("v1:" + v1 + ",   v2:" + v2);
        console.log("v1 len:" + vector.length(v1));
        console.log("v1 multiply-1:" + vector.multiplyNum(v1, 3));
        console.log("dot:" + vector.dot(v1, v2));
        console.log("v1 to v2 Angle:" + vector.getAngleDeg(v1, v2));
        var proj = vector.getProj(v1, v2);
        console.log("v1 to v2 Projection:" + proj);
        console.log("v1 to v2 cross:" + vector.cross(v1, v2));


        var pos = drawAxis();
        vector.drawVector(pos, v1);
        vector.drawVector(pos, v2);
        vector.drawVector(pos, proj);
        drawCircle(pos);

        return pos;
    }

    var vector = {
        drawVector: function (arr, v) {
            arr.push(0.0, 0.0);
            arr.push(v[0], v[1]);
        },
        // ||P|| = √(P1^2 + P2^2 + ...)
        length: function (v1) {
            var result = 0.0;
            for (var i = 0; i < v1.length; i++) {
                result += Math.pow(v1[i], 2.0);
            }
            return Math.sqrt(result, 2.0);
        },
        //和标量相乘
        multiplyNum: function (v1, num) {
            var tg = [];
            for(var i = 0; i < v1.length; i++){
                tg.push(v1[i] * num);
            }
            return tg;
        },
        // P·Q = P1 * Q1 + P2 * Q2 + ...
        dot: function (v1, v2) {
            if (v1.length !== v2.length) {
                throw "向量分量数不一样"
            }
            var result = 0.0;
            for (var i = 0; i < v1.length; i++) {
                result += v1[i] * v2[i];
            }
            return result;
        },
        //P×Q = yz - zy, zx - xz, xy - yx
        cross: function (v1, v2) {
            var x1 = v1[0];
            var y1 = v1[1];
            var z1 = v1[2] | 0.0;

            var x2 = v2[0];
            var y2 = v2[1];
            var z2 = v2[2] | 0.0;

            return [
                y1*z2 - z1*y2,
                z1*x2 - x1*z2,
                x1*y2 - y1*x2
            ]
        },
        //  P·Q = ||P|| ||Q|| cosα
        //  α = acos(P·Q / ||P|| ||Q||)
        getAngleDeg: function (v1, v2){
            var dotRt = this.dot(v1, v2);
            var len = this.length(v1) * this.length(v2);
            var rad = Math.acos(dotRt / len);
            return angle.radToDeg(rad);
        },
        //Pproj = ( P·Q / ||Q||^2) * Q
        getProj: function (v1, v2) {
            var dotRt = this.dot(v1, v2);
            var qLen = this.length(v2);
            return this.multiplyNum(v2, dotRt / qLen);;
        }
    };

    var angle = {
        degToRad: function (deg){
            return deg * (Math.PI / 180.0);
        },
        radToDeg: function (rad) {
            return rad * (180.0 / Math.PI);
        }
    };

    function drawCircle(pos){
        var last = [0.0, 0.0];
        for(var st = 0.0; st <= 360.0; st += 10.0){
            var x = Math.cos(angle.degToRad(st)) * 2.0;
            var y = Math.sin(angle.degToRad(st)) * 2.0;
            pos.push(last[0], last[1], x, y);
            last[0] = x;
            last[1] = y;
        }
    }

    /**
     * 坐标轴
     * @param opt_min 最小值
     * @param opt_max 最大值
     */
    function drawAxis(opt_min, opt_max) {
        var array = [];
        var min = opt_min | -10.0;
        var max = opt_max | 10.0;

        array.push(min, 0);
        array.push(max, 0);
        array.push(max, 0);
        array.push(max - 0.5, -0.12);
        array.push(max, 0);
        array.push(max - 0.5, 0.12);

        array.push(0, min);
        array.push(0, max);
        array.push(0, max);
        array.push(-0.12, max - 0.5);
        array.push(0, max);
        array.push(0.12, max - 0.5);

        for(var i = min; i < max; i++){
            array.push(i, 0.2);
            array.push(i, 0);
        }

        for(var i = min; i < max; i++){
            array.push(0.2, i);
            array.push(0, i);
        }

        return array;
    }

    function main() {
        var pos = cal();
        var ct = pos.length / 2;
        var canvas = document.getElementById("c");
        var gl = canvas.getContext("webgl");

        var program = webglUtils.createProgramFromScripts(gl, ["vs-src", "fs-src"]);
        var a_position = gl.getAttribLocation(program, "a_position");
        var u_projMatrix = gl.getUniformLocation(program, "u_projMatrix");

        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pos), gl.STATIC_DRAW);

        //draw
        draw();

        function draw(){
            webglUtils.resizeCanvasToDisplaySize(gl.canvas);
            gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
            gl.clearColor(0, 0, 0, 1);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.useProgram(program);

            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.enableVertexAttribArray(a_position);
            gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 0, 0);

            gl.uniformMatrix4fv(u_projMatrix, false, proj(gl.canvas.clientWidth, gl.canvas.clientHeight));

            gl.drawArrays(gl.LINES, 0, ct);
        }

        function proj(width, height){
            return [
                1 / 10, 0, 0, 0,
                0, 1 / 10, 0, 0,
                0, 0, 1, 0,
                0, 0, 0, 1,
            ]
        }
    }
</script>
</html>